/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */

/**
 * @version conf.c 0.0.2
 * @author Dr.NP <np@bsgroup.org>
 * @package Comor
 *
 * Configuration parser
 */

#include "bspd.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct param kv;
struct conf setting;

// Initialize configuration parser
int conf_init(char *f)
{
	FILE *fp;
	char line[MAX_CONF_LINE_LENGTH + 1];
	
	memset(&kv, 0, sizeof(kv));

	// Default values
	setting.srv_mode = "";
	setting.srv_daemonize = 1;
	setting.srv_enable_thread = 0;
	setting.srv_worker = 1;
	setting.base_srv_addr = "127.0.0.1";
	setting.base_srv_listen_addr = "0.0.0.0";
	setting.base_srv_port = DEFAULT_BASE_SRV_PORT;
	setting.center_srv_addr = "127.0.0.1";
	setting.center_srv_listen_addr = "0.0.0.0";
	setting.center_srv_port = DEFAULT_CENTER_SRV_PORT;
	setting.status_srv_listen_addr = "0.0.0.0";
	setting.status_srv_port = DEFAULT_STATUS_SRV_PORT;
	setting.login_srv_addr = "127.0.0.1";
	setting.login_srv_listen_addr = "0.0.0.0";
	setting.login_srv_port = DEFAULT_LOGIN_SRV_PORT;
	setting.login_srv_status_port = DEFAULT_LOGIN_SRV_STATUS_PORT;
	setting.coin_srv_listen_addr = "0.0.0.0";
	setting.coin_srv_port = DEFAULT_COIN_SRV_PORT;
	setting.srv_sandbox_str = "";
	setting.mysql_host = "localhost";
	setting.mysql_user = "root";
	setting.mysql_pass = "";
	setting.mysql_default_db = "comoro";
	setting.mysql_sock = "";
	setting.mysql_user_table = "bsp_user";
	setting.mysql_uid_column = "user_uid";
	setting.mysql_uname_column = "user_username";
	setting.mysql_upass_column = "user_password";
	setting.mysql_urid_column = "user_runner_id";
	setting.mysql_ucoin_column = "user_coin";
	setting.mysql_runner_table = "bsp_runner";
	setting.mysql_rid_column = "runner_id";
	setting.mysql_rname_column = "runner_name";
	setting.mysql_rscript_column = "runner_script";
	setting.mysql_rlogin_column = "runner_need_login";
	setting.mysql_banker_table = "bsp_banker";
	setting.mysql_bid_column = "banker_id";
	setting.mysql_bpass_column = "banker_password";
	setting.mysql_brid_column = "banker_runner_id";
	setting.mysql_blevel_column = "banker_level";
	setting.mysql_bamount_column = "banker_amount";
	setting.base_status_interval = 30;
	setting.log_filename = "../log/bspd.log";
	setting.runner_base_dir = "";
	setting.status_file_dir = "";
	
	fp = fopen(f, "r");
	if (!fp)
	{
		fprintf(stderr, "Configuration file not found\n");
		exit(EXIT_IO_ERROR);
	}
	
	while (!feof(fp))
	{
		if (fgets(line, MAX_CONF_LINE_LENGTH, fp) && strlen(line))
		{
			if (conf_parse_line(line))
			{
				conf_eval();
			}
		}
	}
	
	fclose(fp);
	
	return RTN_SUCCESS;
}

// Parse one line
int conf_parse_line(char *line)
{
	int l = strlen(line);
	int ct = 0;
	int s_pos = 0;
	int l_pos = -1;
	int in_space = 1;
	int has_key = 0;
	int in_quote = 0;
	
	if (kv.key)
	{
		free(kv.key);
		kv.key = 0x0;
	}
	
	if (kv.value)
	{
		free(kv.value);
		kv.value = 0x0;
	}
	
	for (ct = 0; ct < l; ct ++)
	{
		if (line[ct] == '\'')
		{
			if (0 == in_quote)
			{
				in_quote = 1;
				line[ct] = 0x0;
			}

			else if (1 == in_quote)
			{
				in_quote = 0;
				line[ct] = 0x0;
			}
		}

		else if (line[ct] == '"')
		{
			if (0 == in_quote)
			{
				in_quote = 3;
				line[ct] = 0x0;
			}

			else if (3 == in_quote)
			{
				in_quote = 0;
				line[ct] = 0x0;
			}
		}
		
		if ((!in_quote && line[ct] <= 0x20) || (in_quote && line[ct] < 0x20))
		{
			in_space = 1;
			line[ct] = 0x0;
			
			if (l_pos > 0 && has_key)
			{
				// Value
				kv.value = strdup(line + l_pos);
				
				return ct;
			}
		}
		
		else if ((';' == line[ct] || '#' == line[ct]) && in_space)
		{
			return 0;
		}
		
		else if ('=' == line[ct] && 0 == has_key)
		{
			// Depart?
			line[ct] = 0x0;
			if (l_pos >= 0)
			{
				kv.key = strdup(line + l_pos);
				has_key = 1;
				l_pos = -1;
				in_space = 1;
			}
		}
		
		else
		{
			// Legal ASCII
			if (1 == in_space)
			{
				l_pos = ct;
				in_space = 0;
				s_pos ++;
			}
		}
	}
	
	return RTN_SUCCESS;
}

// Set value into config
int conf_eval()
{
	if (!kv.key || !kv.value)
	{
		return RTN_MEMORY_ERROR;
	}
	
	if (0 == strlen(kv.key))
	{
		return RTN_UNKNOWN;
	}

	// Fill into setting struct
	if (0 == strncmp(kv.key, "SRV_MODE", 8))
	{
		setting.srv_mode = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "SRV_DAEMONIZE", 13))
	{
		setting.srv_daemonize = (char) atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "SRV_ENABLE_THREAD", 17))
	{
		setting.srv_enable_thread = (char) atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "SRV_WORKER", 10))
	{
		setting.srv_worker = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "BASE_SRV_ADDR", 13))
	{
		setting.base_srv_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "BASE_SRV_LISTEN_ADDR", 20))
	{
		setting.base_srv_listen_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "BASE_SRV_PORT", 13))
	{
		setting.base_srv_port = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "CENTER_SRV_ADDR", 15))
	{
		setting.center_srv_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "CENTER_SRV_LISTEN_ADDR", 22))
	{
		setting.center_srv_listen_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "CENTER_SRV_PORT", 15))
	{
		setting.center_srv_port = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "STATUS_SRV_LISTEN_ADDR", 15))
	{
		setting.status_srv_listen_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "STATUS_SRV_PORT", 15))
	{
		setting.status_srv_port = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "LOGIN_SRV_ADDR", 14))
	{
		setting.login_srv_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "LOGIN_SRV_LISTEN_ADDR", 21))
	{
		setting.login_srv_listen_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "LOGIN_SRV_PORT", 14))
	{
		setting.login_srv_port = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "LOGIN_SRV_STATUS_PORT", 21))
	{
		setting.login_srv_status_port = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "COIN_SRV_LISTEN_ADDR", 13))
	{
		setting.coin_srv_listen_addr = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "COIN_SRV_PORT", 13))
	{
		setting.coin_srv_port = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "SRV_SANDBOX_STR", 15))
	{
		setting.srv_sandbox_str = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_HOST", 10))
	{
		setting.mysql_host = strdup(kv.value);
	}

	else if (0 == strcmp(kv.key, "MYSQL_USER"))
	{
		setting.mysql_user = strdup(kv.value);
	}

	else if (0 == strcmp(kv.key, "MYSQL_PASS"))
	{
		setting.mysql_pass = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_DEFAULT_DB", 16))
	{
		setting.mysql_default_db = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_SOCK", 10))
	{
		setting.mysql_sock = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_USER_TABLE", 16))
	{
		setting.mysql_user_table = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_UID_COLUMN", 16))
	{
		setting.mysql_uid_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_UNAME_COLUMN", 18))
	{
		setting.mysql_uname_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_UPASS_COLUMN", 18))
	{
		setting.mysql_upass_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_URID_COLUMN", 17))
	{
		setting.mysql_urid_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_UCOIN_COLUMN", 18))
	{
		setting.mysql_ucoin_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_RUNNER_TABLE", 18))
	{
		setting.mysql_runner_table = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_RID_COLUMN", 16))
	{
		setting.mysql_rid_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_RNAME_COLUMN", 18))
	{
		setting.mysql_rname_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_RSCRIPT_COLUMN", 20))
	{
		setting.mysql_rscript_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_RLOGIN_COLUMN", 19))
	{
		setting.mysql_rlogin_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_BANKER_TABLE", 18))
	{
		setting.mysql_banker_table = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_BID_COLUMN", 16))
	{
		setting.mysql_bid_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_BPASS_COLUMN", 18))
	{
		setting.mysql_bpass_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_BRID_COLUMN", 17))
	{
		setting.mysql_brid_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_BLEVEL_COLUMN", 19))
	{
		setting.mysql_blevel_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "MYSQL_BAMOUNT_COLUMN", 20))
	{
		setting.mysql_bamount_column = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "BASE_STATUS_INTERVAL", 20))
	{
		setting.base_status_interval = atoi(kv.value);
	}

	else if (0 == strncmp(kv.key, "LOG_FILENAME", 12))
	{
		setting.log_filename = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "RUNNER_BASE_DIR", 15))
	{
		setting.runner_base_dir = strdup(kv.value);
	}

	else if (0 == strncmp(kv.key, "STATUS_FILE_DIR", 15))
	{
		setting.status_file_dir = strdup(kv.value);
	}

	else
	{
		// What are you doing?
	}

	return RTN_SUCCESS;
}
